package com.myCompany.edu.realtime.util;



import com.myCompany.edu.realtime.common.Constant;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.flink.shaded.guava18.com.google.common.base.CaseFormat;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;


/**
 * @author
 * @date 2022/9/17 9:39
 */

public class JdbcUtil {
    public static void main(String[] args) {
        getPhoenixConnection();
    }

    public static Connection getPhoenixConnection() {
        String driver = Constant.PHOENIX_DRIVER;
        String url = Constant.PHOENIX_URL;

        return getJdbcConnection(driver, url, null, null);
    }

    private static Connection getJdbcConnection(String driver, String url, String user, String password) {
        try {
            //先加载驱动
            Class.forName(driver);

            //通过该方法返回一个jdbc的通道
            return DriverManager.getConnection(url, user, password);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void closeConnection(Connection conn) {
        try {
            if (conn != null && !conn.isClosed()) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     *  将通过sql查询的数据封装到一个list集合中
     * @param conn 连接对象
     * @param sql  预处理sql
     * @param args  参数，其实就是id，也只有一个参数
     * @param tClass    pojo的名子
     * @param isCame    判读是否需要转成驼峰的标志位
     * @param <T>   pojo表的泛型
     * @return  返回sql查询的一条数据的集合
     */
    public static <T> List<T> queryList(Connection conn, String sql, Object[] args,
                                        Class<T> tClass, boolean... isCame) {
        //从数据读取的字段名，是否要转成驼峰
        boolean underlineToCame = false;
        if (isCame.length > 0) {
            underlineToCame = isCame[0];
        }

        List<T> list = new ArrayList<>();
        try {
            //1.先根据连接对象获取一个预处理语句
            PreparedStatement ps = conn.prepareStatement(sql);

            //2.sql中有可能会有占位符，给占位符赋值
            for (int i = 0; args != null && i < args.length; i++) {
                ps.setObject(i + 1, args[i]);
            }

            //3.执行查询
            ResultSet resultSet = ps.executeQuery();
            //获取元数据
            ResultSetMetaData metaData = resultSet.getMetaData();
            int columnCount = metaData.getColumnCount();

            //4. 解析查询结果，封装到 T 类型的对象中，存入到List集合中
            while (resultSet.next()) {
                //循环进来一次，表示读取到了结果中的一行数据，把这个一样的每一列数据，封装到一份 T 类型的对象中
                T t = tClass.newInstance(); //创建一个 T 类型的对象，这里不能直接new，只能通过newInstance()方法创建T类型的对象
                for (int i = 1; i <= columnCount; i++) {
                    //获取i个列的列名
                    String name = metaData.getColumnLabel(i);
                    if (underlineToCame) { //如果是 true， 表示把下划线转成驼峰
                        name = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, name);
                    }

                    //获取i个列的数据值
                    Object v = resultSet.getObject(i);

                    /*
                    * 给 t 对象的 name 属性赋值为 v  t.name=value
                    * public static void setProperty(final Object bean, final String name, final Object value)
                    */
                    BeanUtils.setProperty(t, name, v);
                }
                list.add(t);
            }

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        //这个list理论上只有一个元素
        return list;

    }

}
